package com.excilys.capicsoubank.services;

import java.util.List;

import org.apache.commons.lang3.tuple.Pair;
import org.springframework.security.access.annotation.Secured;

import com.excilys.capicsoubank.entities.Transaction;
import com.excilys.capicsoubank.entities.TransactionType;
import com.excilys.capicsoubank.exception.NegativeBalanceException;

/**
 * Service transaction.
 * 
 * @author Sébastien Bihan
 * 
 */
public interface TransactionService {

	/**
	 * La taille de l'historique des transactions en mois.
	 */
	int SIZE_HISTORY = 6;

	/**
	 * Virement interne.
	 * 
	 * @param accountIdSource
	 *            l'id du compte source (non null)
	 * 
	 * @param accountIdDestination
	 *            l'id du compte destination (non null)
	 * 
	 * @param amount
	 *            montant du virement (>0)
	 * @throws NegativeBalanceException
	 *             exception lancée quand le virement applique un découvert non
	 *             autorisé
	 */
	@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
	void transferBetweenAccounts(Integer accountIdSource,
			Integer accountIdDestination, long amount)
			throws NegativeBalanceException;

	/**
	 * Retourne la somme des transactions carte d'un compte pour un mois d'une
	 * année donnée.
	 * 
	 * @param accountId
	 *            l'id du compte (non null)
	 * @param year
	 *            l'année
	 * @param month
	 *            le mois
	 * @return la somme des transactions carte d'un compte pour un mois d'une
	 *         année donnée
	 */
	@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
	long getSumCardTransactionsByYearByMonth(Integer accountId, int year,
			int month);

	/**
	 * Retourne la liste des transactions de types donnés d'un compte triée par
	 * date décroissante et paginée avec le nombre total de transactions sans
	 * pagination.
	 * 
	 * @param accountId
	 *            l'id du compte (non null)
	 * @param year
	 *            l'année
	 * @param month
	 *            le mois
	 * @param types
	 *            un tableau contenant les types de transaction à prendre en
	 *            compte (non vide)
	 * @param page
	 *            le numéro de page demandé (>=1)
	 * @param sizePage
	 *            la taille d'un page
	 * @return la liste des transactions de types donnés d'un compte triée par
	 *         date décroissante et paginée avec le nombre total de transactions
	 *         sans pagination
	 */
	Pair<List<Transaction>, Long> getTransactionByAccountByYearByMonthByTypeWithPagination(
			Integer accountId, int year, int month, TransactionType[] types,
			int page, int sizePage);

	/**
	 * Vérifie que la date demandée est dans l'historique.
	 * 
	 * @param year
	 *            l'année demandée
	 * @param month
	 *            le mois demandé
	 * @return true si la date est dans l'historique, false sinon
	 */
	@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
	boolean isInHistory(int year, int month);
}
